home *** CD-ROM | disk | FTP | other *** search
/ Symantec Visual Cafe for Java 2.5 / symantec-visual-cafe-2.5-database-dev-edition.iso / Visual Cafe Pro v1.0 / SOURCE.BIN / Plasma.java < prev    next >
Encoding:
Java Source  |  1997-06-19  |  12.2 KB  |  454 lines

  1. package symantec.itools.multimedia;
  2.  
  3.  
  4. import java.awt.Canvas;
  5. import java.awt.Dimension;
  6. import java.awt.Graphics;
  7. import java.awt.Image;
  8. import java.awt.image.IndexColorModel;
  9. import java.awt.image.MemoryImageSource;
  10. import symantec.itools.lang.OS;
  11.  
  12.  
  13. /**
  14.  * Plasma component.
  15.  * Creates an animation of colored amorphous shapes, where colors gradually
  16.  * modulate as shapes merge and separate.
  17.  *
  18.  * @version 1.0, Nov 26, 1996
  19.  * @author Symantec
  20.  */
  21.  
  22.  
  23. public class Plasma
  24.     extends Canvas
  25.     implements Runnable
  26. {
  27.     int xpoints[];
  28.     int ypoints[];
  29.  
  30.     byte red[];
  31.     byte green[];
  32.     byte blue[];
  33.  
  34.     byte buffer[];
  35.     byte costab[];
  36.     Dimension dim = null;
  37.     IndexColorModel cModel = null;
  38.     Image img = null;
  39.     byte x1;
  40.     byte x2;
  41.     byte y1;
  42.     byte y2;
  43.     byte x1mod = 6;
  44.     byte x2mod = 8;
  45.     byte y1mod = 6;
  46.     byte y2mod = 4;
  47.  
  48.     boolean keepGoing = true;
  49.     boolean suspended = false;
  50.      boolean stopThread = false;
  51.      boolean Threadstopped = false;
  52.  
  53.     Thread displayThread = null;
  54.  
  55.     private boolean previewMode = false;
  56.  
  57.     /**
  58.      * Create default plasma component.
  59.      */
  60.  
  61.     public Plasma()
  62.     {
  63.         super();
  64.  
  65.         xpoints = new int[5];
  66.         ypoints = new int[5];
  67.         red     = new byte[128];
  68.         green   = new byte[128];
  69.         blue    = new byte[128];
  70.  
  71.         dopalette();
  72.  
  73.         cModel = new IndexColorModel(7, 128, red, green, blue);
  74.         costab = new byte[256];
  75.  
  76.         setupcos();
  77.  
  78.         createBuffer();
  79.     }
  80.  
  81.     void createBuffer()
  82.     {
  83.         dim = size();
  84.         buffer = new byte[dim.width * (dim.height + 100)];
  85.         img = null;
  86.     }
  87.  
  88.     /**
  89.      * Tells this component that it has been added to a container.
  90.      * This is a standard Java AWT method which gets called by the AWT when
  91.      * this component is added to a container. Typically, it is used to
  92.      * create this component's peer.
  93.      *
  94.      * It has been overridden here to start the plasma thread.
  95.      *
  96.      * @see #removeNotify
  97.      */
  98.  
  99.     public synchronized void addNotify()
  100.     {
  101.           super.addNotify();
  102.         displayThread = new Thread(this);
  103.         displayThread.setPriority(Thread.MIN_PRIORITY);
  104.         displayThread.start();
  105.     }
  106.  
  107.     /**
  108.      * Tells this component that it is being removed from a container.
  109.      * This is a standard Java AWT method which gets called by the AWT when
  110.      * this component is removed from a container. Typically, it is used to
  111.      * destroy the peers of this component and all its subcomponents.
  112.      *
  113.      * It has been overridden here to stop the plasma thread.
  114.      *
  115.      * @see #addNotify
  116.      */
  117.     public synchronized void removeNotify() {
  118.           keepGoing = false;
  119.           stopThread = false;
  120.         if (displayThread != null) {
  121.               displayThread.setPriority(Thread.MAX_PRIORITY);
  122.               displayThread.resume();
  123.           }
  124.         while (displayThread != null)
  125.               try { Thread.sleep(40); } catch(Exception e) { };
  126.           super.removeNotify();
  127.     }
  128.  
  129.     /**
  130.      * Resume plasma animation.
  131.      */
  132.  
  133.     public void startPlasma() {
  134.         suspended = false;
  135.         show();
  136.     }
  137.  
  138.     /**
  139.      * Suspend plasma animation.
  140.      */
  141.     public void stopPlasma() {
  142.         suspended = true;
  143.     }
  144.  
  145.     /**
  146.      * Makes this component visible.
  147.      * This is a standard Java AWT method which gets called to show this
  148.      * component. If this component was invisible due to a previous hide()
  149.      * call it make this component visible again.
  150.      *
  151.      * @see #hide
  152.      */
  153.     public synchronized void show() {
  154.          if (displayThread != null) {
  155.               if (stopThread) {
  156.                     stopThread = false;
  157.               }
  158.               else {
  159.                    displayThread.setPriority(Thread.MAX_PRIORITY);
  160.                     displayThread.resume();
  161.               }
  162.         }
  163.     }
  164.  
  165.     /**
  166.      * Makes this component invisible.
  167.      * This is a standard Java AWT method which gets called to hide
  168.      * this component. A hidden component cannot be seen by the user nor
  169.      * does it take up space in its container, but it does continue to
  170.      * exist.
  171.      *
  172.      * @see #show
  173.      */
  174.     public synchronized void hide() {
  175.          if (!Threadstopped) {
  176.              stopThread = true;
  177.              displayThread.setPriority(Thread.MAX_PRIORITY);
  178.          }
  179.      }
  180.  
  181.     /**
  182.      * Moves and/or resizes this component.
  183.      * This is a standard Java AWT method which gets called to move and/or
  184.      * resize this component. Components that are in containers with layout
  185.      * managers should not call this method, but rely on the layout manager
  186.      * instead.
  187.      *
  188.      * @param x horizontal position in the parent's coordinate space
  189.      * @param y vertical position in the parent's coordinate space
  190.      * @param width the new width
  191.      * @param height the new height
  192.      */
  193.     public synchronized void reshape(int    x,
  194.              int    y,
  195.              int    width,
  196.              int    height)
  197.     {
  198.         super.reshape(x,y,width,height);
  199.         createBuffer();
  200.     }
  201.  
  202.    /**
  203.      * Sets the preview mode flag.  This flag is used by Visual Cafe to
  204.      * determine if this component should be run during design time.
  205.      * @param f new preview mode
  206.      * @see #getPreviewMode
  207.      */
  208.     public void setPreviewMode(boolean f)
  209.     {
  210.         previewMode = f;
  211.         invalidate();
  212.     }
  213.  
  214.    /**
  215.      * Gets the preview mode flag. This flag is used by Visual Cafe to
  216.      * determine if this component should be run during design time.
  217.      * @param f new preview mode
  218.      * @see #setPreviewMode
  219.      */
  220.     public boolean getPreviewMode()
  221.     {
  222.         return previewMode;
  223.     }
  224.  
  225.     /**
  226.      * Plasma thread body.  This method is called by the Java virtual
  227.      * machine to when this thread starts.
  228.      */
  229.  
  230.     public void run()
  231.     {
  232.         while (keepGoing) {
  233.  
  234.             if ((!stopThread) && (!suspended) && (previewMode || !symantec.beans.Beans.isDesignTime()))
  235.                 repaint();
  236.  
  237.                 if (stopThread) {
  238.                     super.hide();
  239.                     Threadstopped = true;
  240.                     displayThread.setPriority(Thread.MIN_PRIORITY);
  241.                     displayThread.suspend();
  242.                     Threadstopped = false;
  243.                     if (keepGoing) {
  244.                         super.show();
  245.                         displayThread.setPriority(Thread.MIN_PRIORITY);
  246.                     }
  247.                 }
  248.                 else {
  249.                     if (keepGoing)
  250.                         try { Thread.sleep(100); } catch(Exception e) { };
  251.                 }
  252.         }
  253.           displayThread = null;
  254.     }
  255.  
  256.     private int iteration = 0;
  257.     private final int MAX_ITERATION_GC = 25;
  258.  
  259.     /**
  260.      * Paints this component using the given graphics context.
  261.      * This is a standard Java AWT method which typically gets called
  262.      * by the AWT to handle painting this component. It paints this component
  263.      * using the given graphics context. The graphics context clipping region
  264.      * is set to the bounding rectangle of this component and its <0,0>
  265.      * coordinate is this component's top-left corner.
  266.      *
  267.      * @param g the graphics context used for painting
  268.      * @see java.awt.Component#repaint
  269.      * @see #update
  270.      */
  271.     public void paint(Graphics g)
  272.     {
  273.         if (!suspended && (previewMode || !symantec.beans.Beans.isDesignTime()))
  274.             moveplasma();
  275.  
  276.         //If img is null, we need to create one
  277.         if (img == null)
  278.         {
  279.             drawplasma();
  280.  
  281.             try
  282.             {
  283.                 img = createImage(new MemoryImageSource(dim.width,dim.height,cModel,buffer,0,dim.width));
  284.             }
  285.             catch(Exception e)
  286.             {
  287.             }
  288.         }
  289.  
  290.         if (OS.isMacintosh())
  291.         {
  292.             //Clip the width of the component
  293.             g.clipRect(0, 0, dim.width, dim.height);
  294.         }
  295.  
  296.         //Draw border
  297.         g.drawRect(0, 0, dim.width - 1, dim.height - 1);
  298.  
  299.         //Inset clip 1,1
  300.         g.clipRect(1, 1, dim.width - 2, dim.height - 2);
  301.  
  302.         //Draw plasma image
  303.         if (img != null)
  304.         {
  305.             if (symantec.itools.lang.OS.isMacintosh())
  306.                 g.drawImage(img, 1, 1, null);
  307.             else
  308.                 g.drawImage(img, 1, 1, this);
  309.         }
  310.  
  311.         if (++iteration > MAX_ITERATION_GC) {
  312.             System.gc();
  313.             iteration = 0;
  314.         }
  315.     }
  316.  
  317.     /**
  318.      * Handles redrawing of this component on the screen.
  319.      * This is a standard Java AWT method which gets called by the Java
  320.      * AWT (repaint()) to handle repainting this component on the screen.
  321.      * The graphics context clipping region is set to the bounding rectangle
  322.      * of this component and its <0,0> coordinate is this component's
  323.      * top-left corner.
  324.      * Typically this method paints the background color to clear the
  325.      * component's drawing space, sets graphics context to be the foreground
  326.      * color, and then calls paint() to draw the component.
  327.      *
  328.      * It is overridden here to reduce flicker by eliminating the uneeded
  329.      * clearing of the background.
  330.      *
  331.      * @param g the graphics context
  332.      * @see java.awt.Component#repaint
  333.      * @see #paint
  334.      */
  335.     public void update(Graphics g)
  336.     {
  337.         paint(g);
  338.     }
  339.  
  340.     /**
  341.      * Draws plasma data into an internal buffer.  Not generally called directly.
  342.      */
  343.     public void drawplasma()
  344.     {
  345.         int i;
  346.         int j;
  347.         char t1;
  348.         char t2;
  349.         char t3;
  350.         char t4;
  351.         t3 = (char) (y1);
  352.         t4 = (char) (y2);
  353.  
  354.         for(j = 0; j < dim.height * dim.width; j += dim.width + dim.width + dim.width)
  355.         {
  356.             t1 = (char) (x1);
  357.             t2 = (char) (x2);
  358.  
  359.             for(i = 0; i < dim.width; i += 4)
  360.             {
  361.                 buffer[i + j]              = (byte) ((costab[t1 & 255] +
  362.                                                       costab[t2 & 255] +
  363.                                                       costab[t3 & 255] +
  364.                                                       costab[t4 & 255]));
  365.  
  366.                 buffer[i + j + 1]         = buffer[i + j];
  367.                 buffer[i + j + 2]         = buffer[i + j];
  368.                 buffer[i + j + 3]         = buffer[i + j];
  369.                 buffer[i + j + dim.width]         = buffer[i + j];
  370.  
  371.                 buffer[i + j + dim.width + 1]     = buffer[i + j];
  372.                 buffer[i + j + dim.width + 2]     = buffer[i + j];
  373.                 buffer[i + j + dim.width + 3]     = buffer[i + j];
  374.                 buffer[i + j + dim.width + dim.width]     = buffer[i + j];
  375.  
  376.                 buffer[i + j + dim.width + dim.width + 1] = buffer[i + j];
  377.                 buffer[i + j + dim.width + dim.width + 2] = buffer[i + j];
  378.                 buffer[i + j + dim.width + dim.width + 3] = buffer[i + j];
  379.  
  380.                 t1 += x1mod;
  381.                 t2 += x2mod;
  382.             }
  383.  
  384.             t3 += y1mod;
  385.             t4 += y2mod;
  386.         }
  387.     }
  388.  
  389.     /**
  390.      * Moves Plasma occurance location at random within component.  Not generally called directly.
  391.      */
  392.     public void moveplasma()
  393.     {
  394.         x1 -= x1mod * 2;
  395.         y1 += y1mod * 2;
  396.         x1 += (byte) (Math.random() * 3);
  397.         x2 -= (byte) (Math.random() * 4);
  398.         y1 += (byte) (Math.random() * 3);
  399.         y2 -= (byte) (Math.random() * 5);
  400.  
  401.         //Null the image, so we recreate it
  402.     if (img!=null) img.flush();
  403.         img = null;
  404.     }
  405.  
  406.     /**
  407.      * Setup Plasma Palette.  Not generally called directly.
  408.      */
  409.     public void dopalette()
  410.     {
  411.         int i;
  412.  
  413.         for(i = 0; i < 32; i++)
  414.         {
  415.             red[i]   = (byte) 255;
  416.             green[i] = 0;
  417.             blue[i]  = (byte) (i*8);
  418.         }
  419.  
  420.         for(i = 32; i < 96; i++)
  421.         {
  422.             red[i]   = (byte) (255-(i*8));
  423.             green[i] = (byte) (i*8);
  424.             blue[i]  = (byte) 255;
  425.         }
  426.  
  427.         for(i = 64; i < 96; i++)
  428.         {
  429.             red[i]   = 0;
  430.             green[i] = (byte) 255;
  431.             blue[i]  = (byte) (255-(i*8));
  432.         }
  433.  
  434.         for(i = 96; i < 128; i++)
  435.         {
  436.             red[i]   = (byte) (i*8);
  437.             green[i] = (byte) (255-(i*8));
  438.             blue[i]  = 0;
  439.         }
  440.     }
  441.     /**
  442.      * Setup Plasma cosine table.  Not generally called directly.
  443.      */
  444.     public void setupcos()
  445.     {
  446.         int i;
  447.  
  448.         for(i = 0; i < 256; i++)
  449.         {
  450.             costab[i]=(byte) (16 + Math.cos(((double)i * 360 / 255 / 180) *Math.PI) * 15);
  451.         }
  452.     }
  453. }
  454.